/**
 * 
 */
package com.maywide.jdp.system.spring;

import java.io.Serializable;

import org.springframework.aop.TargetSource;
import org.springframework.scripting.ScriptFactory;
import org.springframework.scripting.ScriptSource;
import org.springframework.util.Assert;
import org.springframework.util.ObjectUtils;

/**
 * @author luoyang
 */
public class ScriptRefreshableTargetSource implements TargetSource, Serializable {
	/**
	 * 
	 */
	private static final long serialVersionUID = -3641122962967986978L;
	
	private ScriptFactory scriptFactory;
	private ScriptSource scriptSource;
	private Object target = null;

	public ScriptRefreshableTargetSource(ScriptFactory scriptFactory,
			ScriptSource scriptSource, Object target) {
		Assert.notNull(target, "Target object must not be null");
		this.scriptFactory = scriptFactory;
		this.scriptSource = scriptSource;
		this.target = target;
	}

	@Override
	public Object getTarget() throws Exception {
		if(this.scriptFactory.requiresScriptedObjectRefresh(this.scriptSource))
			target = this.scriptFactory.getScriptedObject(scriptSource, null);
		return target;
	}

	@Override
	public Class<?> getTargetClass() {
		return this.target.getClass();
	}
	
	public void releaseTarget(Object target) {
		// nothing to do
	}

	public boolean isStatic() {
		return true;
	}

	/**
	 * Two invoker interceptors are equal if they have the same target or if the
	 * targets or the targets are equal.
	 */
	@Override
	public boolean equals(Object other) {
		if (this == other) {
			return true;
		}
		if (!(other instanceof ScriptRefreshableTargetSource)) {
			return false;
		}
		ScriptRefreshableTargetSource otherTargetSource = (ScriptRefreshableTargetSource) other;
		return this.target.equals(otherTargetSource.target);
	}

	/**
	 * SingletonTargetSource uses the hash code of the target object.
	 */
	@Override
	public int hashCode() {
		return this.target.hashCode();
	}

	@Override
	public String toString() {
		return "ScriptRefreshableTargetSource for target object [" + ObjectUtils.identityToString(this.target) + "]";
	}
}
